

import datetime

from rest_framework import serializers
from . import models
from lyapi.settings.contains import CREDIT_TO_MONEY
from django_redis import get_redis_connection
from course.models import Course, CourseExpire
from coupon.models import UserCoupon
from django.db import transaction


class OrderModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Order
        fields = ['pay_type', 'credit', 'coupon', 'order_number']
        extra_kwargs = {
            'pay_type': {'write_only': True},  # 0 1  4
            'credit': {'write_only': True},
            'coupon': {'write_only': True},
            'order_number': {'read_only': True},
        }

    def validate(self, attrs):

        # todo 积分上限限制
        user_credit = self.context['request'].user.credit
        shiyong_credit = attrs.get('credit',0)
        if shiyong_credit > user_credit:
            raise serializers.ValidationError('积分使用超过了上限')

        # todo 校验支付方式
        pay_type = int(attrs.get('pay_type'))  # 0

        if pay_type not in [i[0] for i in models.Order.pay_choices]:
            raise serializers.ValidationError('支付方式选择有误！')

        return attrs
    def create(self, validated_data):
        # 订单号 -- [时间日期， 自增值， userid]

        now = datetime.datetime.now()
        o_date = now.strftime('%Y%m%d%H%M%S')  # 20210105152510
        conn = get_redis_connection('cart')
        o_incr = conn.incr('oincr')  #方法返回的是数字类型
        user_id = self.context['request'].user.id  #self.context['request']  封装的是当前请求对象
        order_number = f'{o_date}{o_incr}{user_id}'  #订单号生成

        # todo 优惠券的真实性或者有效性判断
        coupon_id = validated_data.get('coupon', 0)

        try:
            user_conpon_obj = UserCoupon.objects.get(id=coupon_id, user_id=self.context['request'].user.id,
                                                     is_deleted=False, is_show=True, is_use=False)
        except:
            raise serializers.ValidationError('优惠券不存在')

        u_now = now.timestamp()
        start_time = user_conpon_obj.start_time.timestamp()
        end_time = user_conpon_obj.end_time().timestamp()
        if u_now < start_time or u_now > end_time:
            raise serializers.ValidationError('优惠券不可用或者已经过期')

        condition = user_conpon_obj.coupon.condition
        sale = user_conpon_obj.coupon.sale


        with transaction.atomic():
            sid = transaction.savepoint()
            # 生成订单
            order_obj = models.Order.objects.create(**{
                'order_title': '莽夫学成的订单',
                'total_price': 0,
                'real_price': 0,
                'order_number': order_number,  # 订单号
                'order_status': 0,  # 未支付
                'pay_type': validated_data.get('pay_type', 0),
                'credit': 0,
                'coupon': 0,
                'order_desc': '莽夫要学习',
                'pay_time': now,  # 2020-08-08
                'user_id': user_id,
                # 'user': self.context['request'].user,
            })

            cart_redis_data = conn.hgetall(user_id)

            selected_course = conn.smembers(f'selected_{user_id}')  # 所有选中课程

            total_o_price = 0
            total_real_price = 0
            try:
                for course_bytes_id, expire_bytes_id in cart_redis_data.items():

                    if course_bytes_id in selected_course:

                        course_id = course_bytes_id.decode()
                        expire_id = int(expire_bytes_id.decode())
                        course_obj = Course.objects.get(id=course_id)
                        o_price = float(course_obj.price)  #原价  100, 200

                        # if o_price == 200:
                        #     transaction.savepoint_rollback(sid)

                        r_price = float(course_obj.real_price(expire_id))
                        if expire_id > 0:
                            expire_time = CourseExpire.objects.get(id=expire_id).expire_time
                            expire_text = CourseExpire.objects.get(id=expire_id).expire_text
                        else:
                            expire_time = 100000
                            expire_text = '永久有效'



                        order_detail_obj = models.OrderDetail.objects.create(**{
                            'order': order_obj,
                            'course': course_obj,
                            'expire': expire_time,
                            'expire_text': expire_text,
                            'price': o_price,
                            'real_price': r_price,
                            'discount_name': course_obj.discount_name,
                        })
                        total_o_price += o_price
                        total_real_price += r_price
            except:
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError('下单失败，请联系管理员！')


            if total_real_price < condition:
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError('不符合使用条件')

            # 计算优惠券后的价格
            a = sale[0]
            b = float(sale[1:])
            if a == '-':
                total_real_price -= b
            else:
                total_real_price *= b

            shiyong_credit = validated_data.get('credit', 0)
            if shiyong_credit > total_real_price * CREDIT_TO_MONEY:
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError('积分使用超过了真实价格可用积分的上限')

            # 真实价格要减去积分兑换价格
            total_real_price -= shiyong_credit / CREDIT_TO_MONEY

            order_obj.coupon = coupon_id
            order_obj.credit = shiyong_credit
            order_obj.total_price = total_o_price
            order_obj.real_price = total_real_price
            order_obj.save()

        return order_obj


class OrderDetailModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.OrderDetail
        fields = ['id', 'course_img','course_name','discount_name', 'expire_text']

class OrderDataModelSerializer(serializers.ModelSerializer):
    order_courses = OrderDetailModelSerializer(many=True)
    class Meta:
        model = models.Order
        fields = ['id','order_title','total_price','real_price','order_number','order_status','pay_time','order_courses','order_status_name']
